package com.iraytek.rtsplib;

import android.media.MediaCodec;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Locale;

import pedro.rtsp.utils.ConnectCheckerRtsp;

public class RtspServer {
    private ConnectCheckerRtsp connectCheckerRtsp;
    private int port;
    private String serverIp;
    private boolean isStereo;//立体声
    private int sampleRate;
    private ServerSocket serverSocket;
    private Thread serverThread;
    private ByteBuffer sps, pps, vps;
    private ArrayList<RtspClientThread> clients;

    public RtspServer(ConnectCheckerRtsp connectCheckerRtsp, int port) {
        this.connectCheckerRtsp = connectCheckerRtsp;
        this.port = port;
        serverIp = NetUtil.getIpAddress();
        clients = new ArrayList<>();
    }

    public void startServer() {
        serverThread = new Thread() {
            @Override
            public void run() {
                try {
                    serverSocket = new ServerSocket(port);
                } catch (IOException e) {
                    e.printStackTrace();
                    connectCheckerRtsp.onDisconnectRtsp();
                    return;
                }
                while (!interrupted()) {
                    try {
                        Socket socket = serverSocket.accept();
                        RtspClientThread clientThread = new RtspClientThread(serverIp, port, socket, connectCheckerRtsp)
                                .setMediaParams(isStereo, sampleRate, sps, pps, vps);
                        clients.add(clientThread);
                        clientThread.start();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        serverThread.start();
    }

    public void stopServer() {
        if (serverThread != null) {
            serverThread.interrupt();
        }
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        for (RtspClientThread client : clients) {
            client.stopClient();
        }
        clients.clear();
    }

    public void sendAudio(ByteBuffer buffer, MediaCodec.BufferInfo info) {
        for (RtspClientThread client : clients) {
            if (client.isAlive() && client.canSend())
                client.getRtspSender().sendAudioFrame(buffer.duplicate(), info);//todo why duplicate
        }
    }

    public void setVideoInfo(ByteBuffer newSps, ByteBuffer newPps, ByteBuffer newVps) {
        sps = newSps;
        pps = newPps;
        vps = newVps;
    }


    public void sendVideo(ByteBuffer h264Buffer, MediaCodec.BufferInfo info) {

        for (RtspClientThread client : clients) {
            if (client.isAlive() && client.canSend())
                client.getRtspSender().sendVideoFrame(h264Buffer, info);
        }
    }

    public void setLogs(boolean enable) {
        for (RtspClientThread client : clients) {
            client.getRtspSender().setLogs(enable);
        }
    }

    public void setStereo(boolean stereo) {
        isStereo = stereo;
    }

    public void setSampleRate(int sampleRate) {
        this.sampleRate = sampleRate;
    }

    public String getServerIp() {
        return serverIp;
    }

    public String getINetAddress() {
        return String.format(Locale.ENGLISH, "%s:%s", serverIp, port);
    }
}
